from PySide6.QtWidgets import (
    QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QLineEdit,
    QPushButton, QFileDialog, QSizePolicy, QComboBox
)
from .base_module import BaseModule
from presenter.upload_presenter import UploadPresenter
from view.components.browser_widget import BrowserWidget

from model.common import Common

class UploadModule(BaseModule):
    """上传与部署模块"""

    def __init__(self, server_manager=None):

        self.upload_pr = UploadPresenter(self, server_manager)
        self.common = Common()
        super().__init__()

        self.distribute_file_path = "" # 软件包路径
        self.init_connections()

    def init_ui(self):
        """初始化界面布局"""

        # 软件包配置区
        pkg_group = QGroupBox("从本地选取（文件）")
        pkg_layout = QVBoxLayout(pkg_group)
        pkg_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        # 文件路径选择行
        file_layout = QHBoxLayout()
        file_layout.addWidget(QLabel("软件包:"))
        self.file_path_edit = QLineEdit()
        self.file_path_edit.setPlaceholderText("请选择软件包文件...")
        self.browse_btn = QPushButton("浏览")
        self.upload_btn = QPushButton("上传软件包")
        self.deploy_btn = QPushButton("一键部署")
        file_layout.addWidget(self.file_path_edit)
        file_layout.addWidget(self.browse_btn)
        file_layout.addWidget(self.upload_btn)
        file_layout.addWidget(self.deploy_btn)
        pkg_layout.addLayout(file_layout)

        # MD5 校验
        md5_layout = QHBoxLayout()
        md5_layout.addWidget(QLabel("MD5值:"))
        self.md5_edit = QLineEdit()
        self.md5_edit.setPlaceholderText("请输入软件包MD5校验值（可留空，默认读取配置）...")
        self.verify_btn = QPushButton("校验MD5值")
        md5_layout.addWidget(self.md5_edit)
        md5_layout.addWidget(self.verify_btn)
        pkg_layout.addLayout(md5_layout)

        # 服务器文件选择区
        self.src_group = QGroupBox("从远程服务器选取（文件/目录）")
        self.src_layout = QVBoxLayout(self.src_group)
        self.src_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        # 第一行：服务器选择 + 浏览按钮
        scan_layout = QHBoxLayout()
        scan_layout.addWidget(QLabel("选择源服务器文件/目录:"))
        self.src_ip_combo = QComboBox()
        self.src_ip_combo.setMaximumWidth(180)
        self.src_ip_combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.src_ip_combo.setPlaceholderText("选择源服务器")

        self.src_path = QLabel()
        scan_layout.addWidget(self.src_ip_combo)
        scan_layout.addWidget(self.src_path)
        scan_layout.addStretch()
        self.src_layout.addLayout(scan_layout)

        # 第二行：输入远程路径 + 分发按钮
        scp_layout = QHBoxLayout()
        scp_layout.addWidget(QLabel("目标服务器的路径:"))
        self.remote_path_edit = QLineEdit()
        self.remote_path_edit.setPlaceholderText("输入要传输到目标服务器的路径，例如 /root/test/")
        self.distribute_btn = QPushButton("分发到目标服务器")
        scp_layout.addWidget(self.remote_path_edit)
        scp_layout.addWidget(self.distribute_btn)
        self.src_layout.addLayout(scp_layout)

        # 远程命令区
        self.cmd_group = QGroupBox("命令配置（不保持连接状态）")
        cmd_layout = QHBoxLayout(self.cmd_group)
        self.cmd_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        cmd_layout.addWidget(QLabel("输入命令:"))
        self.run_cmd_edit = QLineEdit()
        self.run_cmd_edit.setPlaceholderText("例如: python3 main.py")
        self.execute_btn = QPushButton("执行命令")
        cmd_layout.addWidget(self.run_cmd_edit)
        cmd_layout.addWidget(self.execute_btn)

        self.layout.addWidget(pkg_group)
        self.layout.addWidget(self.src_group)
        self.layout.addWidget(self.cmd_group)
        self.layout.addStretch()

        for s in self.upload_pr.handle_combo():
            self.src_ip_combo.addItem(f"{s['station']}({s['ip']})", s)

    def init_connections(self):
        """信号连接"""
        self.browse_btn.clicked.connect(self.browse_file)
        self.upload_btn.clicked.connect(self.on_upload)
        self.verify_btn.clicked.connect(self.on_verify)
        self.execute_btn.clicked.connect(self.on_execute)
        self.deploy_btn.clicked.connect(self.on_deploy)
        self.distribute_btn.clicked.connect(self.on_distribute)
        self.src_ip_combo.currentIndexChanged.connect(self.on_browse_remote)

        self.bus.dialog_message.connect(self.update_dialog_status)
        self.bus.bind("mode_change",self.set_enabled_state)
        self.bus.log_message.connect(lambda msg: self.ToastWidget(self, msg)) 
        self.bus.error_message.connect(lambda msg: self.DialogWidget.error(self, "Error", msg))

    def browse_file(self):
        """文件选择对话框"""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "选择软件包",
            "",
            "All Files (*);"
        )
        if file_path:
            self.file_path_edit.setText(file_path)

    def on_upload(self):
        """上传软件包"""
        path = self.file_path_edit.text()
        if not path: 
            self.ToastWidget(self, "请选择文件")
            return
        self.upload_pr.handle_upload(path)

    def on_verify(self):
        """MD5 校验"""
        md5_value = self.md5_edit.text().strip() or self.upload_pr.expected_md5
        self.upload_pr.handle_verify(self.file_path_edit.text(), md5_value)

    def on_execute(self):
        """执行远程命令"""
        command = self.run_cmd_edit.text().strip()
        if not command:
            self.ToastWidget(self, "请输入要执行的命令")
            return
        self.upload_pr.handle_execute(command)

    def on_deploy(self):
        """一键部署"""
        path = self.file_path_edit.text()
        if not path: 
            self.ToastWidget(self, "请选择文件")
            return
        self.upload_pr.handle_deploy(path)

    def set_enabled_state(self, unlocked: bool):
        for i in [self.upload_btn, self.md5_edit, self.verify_btn]:
            i.setEnabled(unlocked)
        self.src_group.setEnabled(unlocked)
        self.cmd_group.setEnabled(unlocked)

    def on_browse_remote(self):
        """浏览源服务器上的文件或目录"""
        data = self.src_ip_combo.currentData()
        dlg = BrowserWidget(data)
        if dlg.exec():
            self.distribute_file_path = dlg.get_selected_path()
            self.src_path.setText("选择的源服务器文件/目录路径为: " + self.distribute_file_path)
            self.setStyleSheet("color: red;")

    def on_distribute(self):
        """将远程文件/目录从源服务器分发到选中目标"""
        src_server = self.src_ip_combo.currentData()
        if not src_server:
            self.bus.log_message.emit("请选择源服务器")
            return
        remote_path = self.remote_path_edit.text().strip()
        if not remote_path:
            self.bus.log_message.emit("请输入目标路径")
            return

        self.upload_pr.handle_distribute(src_server, self.distribute_file_path, remote_path)

    def update_dialog_status(self, results):
        """根据结果弹窗提示"""
        success_msgs = []
        error_msgs = []

        for ip, r in results.items():
            if r.get("status", False):
                msg = r.get("msg", "") or r.get("stdout") or "操作成功"
                success_msgs.append(f"{ip}：{msg}")
            else:
                err = r.get("error") or r.get("stderr") or "未知错误"
                error_msgs.append(f"{ip}：{err}")

        if error_msgs:
            print(error_msgs)
            msg = "\n".join(error_msgs)
            self.DialogWidget.error(self, "Error", msg)
        elif success_msgs:
            msg = "\n".join(success_msgs)
            self.DialogWidget.info(self, "Info", msg)
